Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade path for the zookeeper persistence issue #228

Merged
merged 3 commits into from
Dec 3, 2018

Conversation

solsson
Copy link
Contributor

@solsson solsson commented Dec 2, 2018

#227 for a v4.3.1 release, fixing #89, with an upgrade path to migrate your zookeeper state. Recovery from snapshots is an alternative, but I haven't looked into that.

v5.0.0 hasn't been out long enough for anyone to run anything important on, I suppose. Thus we should focus on how to migrate a 4.3.0 installation, that might have been running since v2.0.0. After this upgrade I think that it'll be a straightforward kubectl replace to go to v5.0.1.

Fixes #89, "logs" which are actually data would end up outside the mount.

Zookeeper's startup logs are more clear than the property file entries:
INFO Created server with tickTime 2000 minSessionTimeout 4000 maxSessionTimeout 40000 datadir /var/lib/zookeeper/log/version-2 snapdir /var/lib/zookeeper/data/version-2
@solsson solsson changed the base branch from master to 4.3.x December 2, 2018 13:12
@solsson
Copy link
Contributor Author

solsson commented Dec 2, 2018

Edit: Got an idea for a less risky upgrade flow that doesn't require downtime and doesn't involve filesystem operations on running pods. See new comment below.

First step of an upgrade is to take a healthy cluster and replace the ephemeral zoo with a updated variant. No need to migrate data.

kubectl replace -f zookeeper/10zookeeper-config.yml
kubectl delete -f zookeeper/51zoo.yml && kubectl apply -f zookeeper/51zoo.yml

Now take a pause and make sure your cluster is still working. When everything is stable do:

kubectl -n kafka exec pzoo-2 -- bash -c 'cd /var/lib/zookeeper && mkdir data/data && mv data/myid data/version-2 data/data/ && cp -r log data/'
kubectl -n kafka exec pzoo-1 -- bash -c 'cd /var/lib/zookeeper && mkdir data/data && mv data/myid data/version-2 data/data/ && cp -r log data/'
kubectl -n kafka exec pzoo-0 -- bash -c 'cd /var/lib/zookeeper && mkdir data/data && mv data/myid data/version-2 data/data/ && cp -r log data/'
kubectl delete -f zookeeper/50pzoo.yml && kubectl apply -f zookeeper/50pzoo.yml

Check for example kubectl -n kafka exec pzoo-0 -- ls -lR /var/lib/zookeeper before and after. This process obviously comes with no guarantees. A file-system level backup of /var/lib/zookeeper from all 5 pods is recommended.

@solsson
Copy link
Contributor Author

solsson commented Dec 2, 2018

Not recommended for production yet, but I upgraded to v5.0.1 after the above, like so:

kubectl apply -f kafka/
kubectl delete -f kafka/50kafka.yml && kubectl apply -f kafka/50kafka.yml
# pause here to await readiness
kubectl apply -f zookeeper/
kubectl delete -f zookeeper/51zoo.yml && kubectl apply -f zookeeper/51zoo.yml
# pause here to await radiness
kubectl delete -f zookeeper/50pzoo.yml && kubectl apply -f zookeeper/50pzoo.yml

@solsson solsson requested a review from atamon December 2, 2018 15:33
@solsson
Copy link
Contributor Author

solsson commented Dec 2, 2018

An upgrade flow that can avoid downtime, I think, is to make use of the fact that zoo has ephemeral storage and kubectl apply is allowed for the configmap and (to quote the error message from apply or replace on the statefulset) "updates to statefulset spec for fields other than 'replicas', 'template', and 'updateStrategy' are forbidden."

Thus we can scale up zoo to form a majority, by applying https://github.com/Yolean/kubernetes-kafka/compare/v4.3.0...4.3.1-upgrade-preparations?expand=1` and then allow ourselves to ignore the data lost when restarting pzoo pods (backup recommended as always).

Note that for the configmap to have effect you must delete the old pods one by one after the two new pods have become ready. The suggested order is zoo-1, zoo-0 (and now is a good time to check logs of zoo pods), pzoo-2, pzoo-1, pzoo-0.

After that comes the risky part: you can switch to the v4.3.1 release, apply 0ed261f there, apply the configmap again and then delete+apply as above the pzoo statefulset. Between delete and apply you might want to delete the pzoo volumes to avoid an old snapshots dir in your volumes.

Finally revert the +2 scale patch, apply the configmap, delete the pzoo pods one by one to give them the majority, delete+apply zoo.

As you can see ideas in #225 are most welcome.

Note that pzoo is more difficult to scale, because you'd have to edit the ID_OFFSET and restart zoo pods as well, and at some point in this process you risk id collisions.

@solsson
Copy link
Contributor Author

solsson commented Dec 3, 2018

I ran the above upgrade flow now using the commands below. That this is not a script: you need to run the commands one by one and make sure everything is up and healthy inbetween:

# not a script, everything must become ready again after every step
git checkout 4.3.1-upgrade-preparations
kubectl apply -f zookeeper/
kubectl -n kafka delete pod zoo-1
kubectl -n kafka delete pod zoo-0
kubectl -n kafka delete pod pzoo-2
kubectl -n kafka delete pod pzoo-1
kubectl -n kafka delete pod pzoo-0
git checkout v4.3.1
git cherry-pick 0ed261f
kubectl apply -f zookeeper/10zookeeper-config.yml
kubectl delete -f zookeeper/50pzoo.yml
kubectl apply -f zookeeper/50pzoo.yml
git checkout v4.3.1
kubectl apply -f zookeeper/10zookeeper-config.yml 
kubectl -n kafka delete pod pzoo-2
kubectl -n kafka delete pod pzoo-1
kubectl -n kafka delete pod pzoo-0
kubectl delete -f zookeeper/51zoo.yml
kubectl apply -f zookeeper/51zoo.yml

I had tests and eventrouter running, with no interruptions. I also tested deletion of kafka pods after the delete steps and everything restarted normally. I deleted two of the three pzoo volume claims, which shows that deletion is optional.

@solsson solsson merged commit f96c755 into 4.3.x Dec 3, 2018
@solsson
Copy link
Contributor Author

solsson commented Dec 3, 2018

I think it's actually possible to upgrade using apply only, no deletion of statefulset. Probably without the need to scale up zoo. The reason I had to delete was that I was working with #227 i.e. version 5.0+ when this issue was discovered.

Edit: Which means #228 (comment), with other git tag names, is our upgrade flow to v5.0.3 :)

@solsson
Copy link
Contributor Author

solsson commented Dec 7, 2018

Confirmed. I've upgraded without scaling:

Directly from v4.3.1, no additional patch:

kubectl apply -f zookeeper/10zookeeper-config.yml
kubectl apply -f zookeeper/51zoo.yml
kubectl apply -f zookeeper/50pzoo.yml
# ... pause, wait for readiness ...
kubectl -n kafka delete pod zoo-1
# ... pause, wait for readiness ...
kubectl -n kafka delete pod zoo-0
# ... pause, wait for readiness ...
kubectl -n kafka exec pzoo-2 -- bash -c 'cd /var/lib/zookeeper && mkdir data/data && mv data/myid data/version-2 data/data/ && cp -r log data/' && kubectl -n kafka delete pod pzoo-2
# ... pause, wait for readiness ...
kubectl -n kafka exec pzoo-1 -- bash -c 'cd /var/lib/zookeeper && mkdir data/data && mv data/myid data/version-2 data/data/ && cp -r log data/' && kubectl -n kafka delete pod pzoo-1
# ... pause, wait for readiness ...
kubectl -n kafka exec pzoo-0 -- bash -c 'cd /var/lib/zookeeper && mkdir data/data && mv data/myid data/version-2 data/data/ && cp -r log data/' && kubectl -n kafka delete pod pzoo-0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant